<template>
  <div class="role">
    <n-card size="small" class="search">
      <CustomSearch
        :form-model="search.criteria"
        :form-list="searchFormList"
        @handle-cancel="handleSearchReset"
        @handle-submit="init"
      />
    </n-card>
    <n-card :title="$t('menu.role_management')" size="small">
      <template #header-extra>
        <HeaderButtons
          :loading="loading"
          @create="handleCreate"
          @export="handleExport"
          @delete-batch="handleDeleteBatch"
          @refresh="init"
        >
          <template #columns>
            <n-checkbox-group v-model:value="checkedColumnsKeys">
              <n-space vertical>
                <n-checkbox
                  v-for="(item, index) in checkboxOptions"
                  :key="index"
                  :value="item.value"
                  :label="item.label"
                />
              </n-space>
            </n-checkbox-group>
          </template>
        </HeaderButtons>
      </template>
      <CustomTable
        v-model:checked-row-keys="checkedRowKeys"
        :row-key="(row: any) => row.id"
        :columns="filteredColumns"
        :data="tableData"
        :search="search"
      />
    </n-card>
    <CustomModal
      v-model:show="modalShow"
      :title="modalType === 'create' ? $t('common.create') : $t('common.edit')"
      :form-model="modalFormData"
      :form-list="modalFormList"
      :form-rules="modalFormRules"
      @handle-modal-cancel="handleModalCancel"
      @handle-modal-submit="handleModalSubmit"
    />
    <CustomDetails v-model:show="detailsShow" :list="detailsDataList" :data="detailsData" />
  </div>
</template>
<script setup lang="ts">
import { getRoleList } from '@/apis/index'
import { RoleCriteria } from '@/apis/role/type/dto'
import { RoleItem } from '@/apis/role/type/vo'
import CustomDetails from '@/components/CustomDetails.vue'
import CustomModal from '@/components/CustomModal.vue'
import CustomSearch from '@/components/CustomSearch.vue'
import CustomTable from '@/components/CustomTable.vue'
import { useRef } from '@/hooks'
import { SearchDto } from '@/types/dto'
import { PaginatedResponse } from '@/types/interface'
import { catchToTuple } from '@/utils'

import HeaderButtons from './components/HeaderButtons.vue'
import { useDetails } from './useDetails'
import { useModal } from './useModal'
import { useSearchForm } from './useSearch'
import { useTable } from './useTable'

const [search, handleSearchReset] = useRef<SearchDto<RoleCriteria>>({
  page: 1,
  pageSize: 10,
  criteria: {
    key: null,
    name: null,
    status: null,
    create_time: null,
  },
})

const tableData = ref<PaginatedResponse<RoleItem>>({
  list: [],
  total: 0,
  page: 1,
  pageSize: 10,
})

const init = async () => {
  loading.value = true
  const [err, data] = await catchToTuple(getRoleList(search.value))
  if (err) {
    loading.value = false
    return
  }

  if (data.code === 200 && data.data) {
    loading.value = false
    tableData.value.list = data.data.list
    tableData.value.total = data.data.total
  }
}

const { searchFormList } = useSearchForm()

const { modalShow, modalType, modalFormData, modalFormList, modalFormRules, handleModalCancel, handleModalSubmit } =
  useModal({ init })

const { detailsShow, detailsData, detailsDataList } = useDetails()

const {
  loading,
  checkedRowKeys,
  checkboxOptions,
  checkedColumnsKeys,
  filteredColumns,
  handleCreate,
  handleExport,
  handleDeleteBatch,
} = useTable({ modalShow, modalType, modalFormData, detailsShow, detailsData, init })

onMounted(() => {
  init()
})
</script>

<style scoped lang="less">
.role {
  height: 100%;

  .search {
    margin-bottom: 10px;
  }
}
</style>
